/* 数据库服务类 */

#pragma once
#include <iostream>
#include <mysql/mysql.h>
#include <vector>
#include <string>
#include <jsoncpp/json/json.h>

#define HOST "101.43.7.28"
#define USER "root"
#define PASSWD "19683250"
#define DB "chat_system"
#define DBPORT 3306

class DataBaseSvr
{
private:
    /* mysql语句执行接口
     * */
    bool MysqlQuery(const std::string& sql)
    {
        if(mysql_query(_mysql, sql.c_str()) != 0)
        {
            // 执行失败
            std::cout << "mysql_query faild in:" << sql << std::endl;
            return false;
        }
        return true;
    }

public:
    DataBaseSvr()
    {
        _mysql = NULL;
    }
    ~DataBaseSvr()
    {
        if(_mysql != NULL)
        {
            mysql_close(_mysql);
        }
    }

    /* 1.初始化mysql操作句柄
     * 连接mysql服务端，设置character_set
     * */
    bool MysqlInit()
    {
        _mysql = mysql_init(NULL);
        if(_mysql == NULL)
        {
            std::cout << "mysql_init failed" << std::endl;
            return false;
        }
        
        if(mysql_real_connect(_mysql, HOST, USER, PASSWD, DB, DBPORT, NULL, 0) == NULL)
        {
            std::cout << "mysql_real_connect failed" << std::endl;
            mysql_close(_mysql);
            return false;
        }

        mysql_set_character_set(_mysql, "utf8");
        return true;
    }

    /* 2.获取所有user info
     *  参数为Json对象，为出参
     * */
    bool GetAllUser(Json::Value* all_user)
    {
        #define GETALLUSER "select * from user;"

        // a.执行sql语句
        if(MysqlQuery(GETALLUSER) == false)
        {
            return false;
        }

        // b.获取结果集
        MYSQL_RES* res = mysql_store_result(_mysql);
        if(res == NULL)
        {
            std::cout << "mysql_store_result failed" << std::endl;
            return false;
        }

        // c.获取单行数据
        int row_nums = mysql_num_rows(res);
        for(int i = 0; i < row_nums; ++i)
        {
            MYSQL_ROW row = mysql_fetch_row(res);
            
            // d.将单行数据组织为临时Json对象
            Json::Value js_tem;
            js_tem["userid"] = atoi(row[0]);
            js_tem["nickname"] = row[1];
            js_tem["school"] = row[2];
            js_tem["telnum"] = row[3];
            js_tem["passwd"] = row[4];

            all_user->append(js_tem);
        }
        
        mysql_free_result(res);
        return true;
    }

    /* 3.获取单个用户的好友信息
     * */
    bool GetFriend(int userid, std::vector<int>* f_id)
    {
        #define GETFRIEND "select friend from friendinfo where userid='%d';" 
        
        // a.格式化sql语句
        char sql[1024] = {0};
        sprintf(sql, GETFRIEND, userid);

        // b.执行sql语句
        if(MysqlQuery(sql) == false)
        {
            return false;
        }

        // c.获取结果集
        MYSQL_RES* res = mysql_store_result(_mysql);
        if(res == NULL)
        {
            std::cout << "mysql_store_result failed" << std::endl;
            return false;
        }

        // d.获取单行数据
        int row_nums = mysql_num_rows(res);
        for(int i = 0; i < row_nums; ++i)
        {
            MYSQL_ROW row = mysql_fetch_row(res);
            f_id->push_back(atoi(row[0]));
        }

        mysql_free_result(res);
        return true;
    }
    
    /* 4.插入新注册用户信息
     * */
    bool InsertUser(int userid, const std::string& nickname, const std::string& school
            , const std::string& telnum, const std::string& passwd)
    {
        #define INSERTUSER "insert into user(userid, nickname, school, telnum, passwd) values('%d', '%s', '%s', '%s', '%s');"
        
        // a.格式化sql语句
        char sql[1024] = {0};
        sprintf(sql, INSERTUSER, userid, nickname.c_str(), school.c_str(), telnum.c_str(), passwd.c_str());

        // b.执行sql语句
        if(MysqlQuery(sql) == false)
        {
            return false;
        }
        return true;
    }

    /* 5.添加用户好友信息
     * */
    bool InsertFriend(int userid1, int userid2)
    {
        #define INSERTFRIEND "insert into friendinfo values('%d', '%d');"
        
        // a.格式化sql语句
        char sql[1024] = {0};
        sprintf(sql, INSERTFRIEND, userid1, userid2);

        // b.执行sql语句
        if(MysqlQuery(sql) == false)
        {
            return false;
        }
        return true;
    }

private:
    MYSQL* _mysql;
};
